package controllers;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

//import org.json.JSONObject;




import java.util.Map;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

import models.PlayPlayer;
import models.PlayTable;
import models.Players;
import models.Tables;
import play.data.DynamicForm;
import play.data.Form;
import play.libs.Json;
import play.mvc.*;

public class PokerPlay extends Controller {
	public static Result askForJoin(long tableId) {
		String userID = session("usrId");
		if(userID == null) return redirect(routes.Application.index());
		boolean err = false;
		long usrid = 0;
		try {
			usrid = Long.parseLong(userID);
		} catch(NumberFormatException e) {
			err = true;
		}
		PlayPlayer pl = Players.getPlayer(usrid);
		if(pl == null) err = true;
		
		PlayTable t = Tables.getTable(tableId);
		if(t == null) err = true;
		if(err) {
			return incorrectID();
		}
		// trzeba jeszcze przypisac graczowi wartosc zetonow przyslugujacych graczom
		if(t.isStarted()) return badRequest(views.html.textmsg.render("Nie mozna dolaczyc do stolu - rozpoczal juz gre.", routes.Application.index().absoluteURL(request())));
		if(!t.addHumanPlayer(usrid, pl)) return badRequest(views.html.textmsg.render("Nie mozna dolaczyc do stolu. Prosze wrocic przyciskiem ponizej i wybrac inny stol.", routes.Application.index().absoluteURL(request())));
		session("usrTable", Long.toString(tableId));
		//return ok(pl.getPlayerName() + " prosi o mozliwosc udzialu w stole " + Tables.getTable(tableId).getTableName());
		t.addMessage("Gracz " + pl.getNazwa() + " dolaczyl do gry.");
		return redirect(routes.PokerPlay.game());
	}
	
	private static Result incorrectID() {
		session().clear();
		return badRequest(views.html.textmsg.render("Użytkownik powiązany jest z nieprawidlowym identyfikatorem. Prosze sprobowac dolaczyc do stolu/utworzyc stol jeszcze raz.", routes.Application.index().absoluteURL(request())));
	}
	
	private static Result nullTable() {
		return badRequest(views.html.textmsg.render("Użytkownik nie jest powiazany z zadna rozgrywka. Prosze sprobowac dolaczyc do stolu/utworzyc stol jeszcze raz.", routes.Application.index().absoluteURL(request())));
	}
	
	private static Result recievedIncorrectData() {
		return badRequest(views.html.textmsg.render("Przeslano nieprawidlowe dane.", routes.Application.index().absoluteURL(request())));
	}
	
	public static Result getPossibleActions() {
		String usrId = session("usrId");
		if(usrId == null) return incorrectID();
		String userTable = session("usrTable");
		if(userTable == null) return nullTable();
		long tableId = Long.parseLong(userTable);
		long userId = Long.parseLong(usrId);
		ObjectNode result = Json.newObject();
		PlayTable pt = Tables.getTable(tableId);
		if(pt == null) return nullTable();
		result.put("messageCount", pt.getMessagesCount());
		if(pt.getCurrentPlayerId() == userId) {
			result.put("actions", pt.getAvaibleActionsForCurrentPlayer());
			result.put("timeForAnswer", pt.answerTime);
			new PlayerAutoAction(pt, userId, 6 /*fold*/, null, (pt.answerTime + 2) * 1000);
		}
		return ok(result); //
	}
	
	public static Result doActionJSON() {
		JsonNode json = request().body().asJson();
		if(json == null)
			return recievedIncorrectData();
		String usrId = session("usrId");
		if(usrId == null) return incorrectID();
		String userTable = session("usrTable");
		if(userTable == null) return nullTable();
		long tableId = Long.parseLong(userTable);
		long userId = Long.parseLong(usrId);
		JsonNode node = json.findPath("actionId");
		if(!node.canConvertToInt()) return recievedIncorrectData();
		int actionId = node.asInt();
		List<Object> dodatkoweParametry = new ArrayList<Object>();
		Iterator<JsonNode> iterator = json.findPath("params").iterator();
		while(iterator.hasNext()) {
			node = iterator.next();
			if(node.isNull()) break;
			if(node.isInt())
				dodatkoweParametry.add(node.asInt());
		}
		PlayTable pt = Tables.getTable(tableId);
		if(pt == null) return nullTable();
		pt.performAction(actionId, userId, dodatkoweParametry.toArray());
		return ok();
	}
	
	public static Result getMessages() {
		String tableId = session("usrTable");
		if(tableId == null) return nullTable();
		PlayTable pt = Tables.getTable(Long.parseLong(tableId));
		if(pt == null) return nullTable();
		return ok(pt.getMessages());
	}
	
	public static Result game() {
		String table = session("usrTable");
		String user = session("usrId"); 
		if(user == null || table == null) return redirect(routes.Application.index());
		PlayTable pt = Tables.getTable(Long.parseLong(table));
		long userL = Long.parseLong(user);
		if(pt == null) return nullTable();
		PlayPlayer player = Players.getPlayer(userL);
		if(player == null) return incorrectID();
		Map<String,Boolean> avActions = pt.getActionsForPlayer(userL);
		boolean shouldWait = false;
		if(avActions.containsKey("wait")) {
			shouldWait = avActions.get("wait");
		}
		/*
		if(!pt.isStarted()) {
			return ok(views.html.game.render(pt.getState(), pt.getMessages(), false, false, true, false, false, false, false, false, false, false, false, false));
		} else if(userL != pt.getCurrentPlayerId()) {
			return ok(views.html.game.render(pt.getState(), pt.getMessages(), true, false, false, false, false, false, false, false, false, false, false, false));
		} else {
			boolean[] actions = pt.getActionTableForCurrentUser();
			return ok(views.html.game.render(pt.getState(), pt.getMessages(), false, false, actions[1], actions[2], actions[3], actions[4], actions[5], actions[6], actions[7], actions[8], actions[9], actions[10], ))
		}*/
		return ok(views.html.game.render(player.getNazwa(), player.cash, pt.getState(), pt.getMessages(), shouldWait, avActions));
	}
	
	public static Result getPlayersCard(long usrid, long tableId) {
		String[] elementy = Tables.getTable(tableId).getPlayerByServerId(usrid).getCardsName();
		if(elementy.length != 5) return recievedIncorrectData();
		return ok(views.html.cardhand.render(elementy[0], elementy[1], elementy[2], elementy[3], elementy[4]));
	}
	
	public static Result getMessageState() {
		String table = session("usrTable");
		if(table == null) return nullTable();
		PlayTable pt = Tables.getTable(Long.parseLong(table));
		long ret = 0;
		if(pt != null) ret = pt.getState();
		return ok(Long.toString(ret));
	}
	
	public static Result performAction() {
		DynamicForm requestData = Form.form().bindFromRequest();
		String command = requestData.get("command");
		String params = requestData.get("params");
		if(command == null) return badRequest();
		Object[] parsedparams = null;
		if(params != null) {
			String[] pr = params.split(";");
			parsedparams = new Object[pr.length];
			for(int i = 0; i < pr.length; ++i) {
				parsedparams[i] = Integer.parseInt(pr[i]);
			}
		}
		String usrId = session("usrId");
		String usrTable = session("usrTable");
		long userid = Long.parseLong(usrId);
		long usertable = Long.parseLong(usrTable);
		PlayTable pt = Tables.getTable(usertable);
		PlayPlayer plr = Players.getPlayer(userid);
		if(pt == null) return nullTable();
		if(plr == null) return incorrectID();
		if(!pt.performActionForPlayer(userid, command, parsedparams)) return badRequest();
		if(!pt.isStarted() && pt.canStart()) {
			pt.start();
		} else if(pt.isStarted()){
			if(pt.next() == null) // trzeba przejśc do nastepnej fazy
				pt.nextPhase();
		}
		
		if(command.compareTo("takecards") == 0 || command.compareTo("changecards") == 0) {
			String[] dck = plr.getCardsName();
			return ok(views.html.cardhand.render(dck[0], dck[1], dck[2], dck[3], dck[4]));
		}
		return ok();
	}
}
